home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Applications / RTrace 1.0 / source / csg_2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-17  |  4.5 KB  |  138 lines  |  [TEXT/KAHL]

  1. /*
  2.  * Copyright (c) 1988, 1992 Antonio Costa, INESC-Norte.
  3.  * All rights reserved.
  4.  *
  5.  * This code received contributions from the following people:
  6.  *
  7.  *  Roman Kuchkuda      - basic ray tracer
  8.  *  Mark VandeWettering - MTV ray tracer
  9.  *  Augusto Sousa       - overall, shading model
  10.  *  Craig Kolb          - CSG
  11.  *
  12.  * Redistribution and use in source and binary forms are permitted
  13.  * provided that the above copyright notice and this paragraph are
  14.  * duplicated in all such forms and that any documentation,
  15.  * advertising materials, and other materials related to such
  16.  * distribution and use acknowledge that the software was developed
  17.  * by Antonio Costa, at INESC-Norte. The name of the author and
  18.  * INESC-Norte may not be used to endorse or promote products derived
  19.  * from this software without specific prior written permission.
  20.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  21.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  22.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  23.  */
  24. #include "defs.h"
  25. #include "extern.h"
  26. #include "csg.h"
  27.  
  28. /**********************************************************************
  29.  *    RAY TRACING - CSG - Version 7.3.1                               *
  30.  *                                                                    *
  31.  *    MADE BY    : Antonio Costa, INESC-Norte, June 1992              *
  32.  *    MODIFIED BY: Antonio Costa, INESC-Norte, July 1992              *
  33.  **********************************************************************/
  34.  
  35. /***** CSG *****/
  36.  
  37. extern tree_struct tree;
  38. extern hit_struct hit_global;
  39.  
  40. /* Main CSG functions */
  41.  
  42. real
  43. csg_sec_intersect(csg_object, position, vector, csg_hit, min_distance)
  44.   object_ptr      csg_object;
  45.   xyz_ptr         position, vector;
  46.   hit_ptr         csg_hit;
  47.   real            min_distance;
  48. {
  49.   real            distance;
  50.   REG real        distance1, distance2;
  51.   xyz_struct      new_position, new_vector;
  52.   csg_ptr         csg;
  53.   hit_ptr         hit1, hit2, hit;
  54.   static hit_struct      hit1_list;
  55.   hit_struct      hit2_list;
  56.  
  57.   if (csg_object->transf != NULL)
  58.   {
  59.     transform(csg_object->transf, position, &new_position);
  60.     transform_vector(csg_object->transf, position, vector, &new_position,
  61.                      &new_vector);
  62.     NORMALIZE(new_vector);
  63.   } else
  64.   {
  65.     STRUCT_ASSIGN(new_position, *position);
  66.     STRUCT_ASSIGN(new_vector, *vector);
  67.   }
  68.   REALINC(csg_tests);
  69.   csg = (csg_ptr) csg_object->data;
  70.   /* CSG intersection */
  71.   hit1 = &hit1_list;
  72.   hit2 = &hit2_list;
  73.   hit1->nodes = 0;
  74.   hit2->nodes = 0;
  75.   POSINC(tree.depth);
  76.   if (tree.depth >= CSG_NODES_MAX)
  77.     runtime_abort("too big CSG TREE PATH");
  78.   SAVE_TREE_PATH(PATH_LEFT);
  79.   distance1 = object_intersect(object[csg->left], &new_position,
  80.                    &new_vector, hit1, min_distance);
  81.   if ((distance1 < min_distance) AND((csg->op == CSG_SUBTRACTION)
  82.       OR(csg->op == CSG_INTERSECTION)))
  83.   {
  84.     POSDEC(tree.depth);
  85.     return 0.0;
  86.   }
  87.   SAVE_TREE_PATH(PATH_RIGHT);
  88.   distance2 = object_intersect(object[csg->right], &new_position,
  89.                    &new_vector, hit2, min_distance);
  90.   POSDEC(tree.depth);
  91.   if ((distance2 < min_distance) AND((csg->op == CSG_INTERSECTION)
  92.       OR((hit1->nodes == 0) AND(csg->op == CSG_UNION))))
  93.     return 0.0;
  94.   if (distance1 < min_distance)
  95.     distance1 = INFINITY;
  96.   if (distance2 < min_distance)
  97.     distance2 = INFINITY;
  98.   if ((distance1 > distance2) AND((csg->op == CSG_UNION)
  99.       OR(csg->op == CSG_INTERSECTION)))
  100.   {
  101.     distance = distance2;
  102.     distance2 = distance1;
  103.     distance1 = distance;
  104.     hit1 = &hit2_list;
  105.     hit2 = &hit1_list;
  106.   }
  107.   switch(csg->op)
  108.   {
  109.   case CSG_UNION:
  110.     if (csg_union(&new_position, &new_vector, hit1, hit2,
  111.           distance1, distance2, &hit, &distance))
  112.       return 0.0;
  113.     break;
  114.   case CSG_SUBTRACTION:
  115.     if (csg_subtraction(&new_position, &new_vector, hit1, hit2,
  116.             distance1, distance2, &hit, &distance))
  117.       return 0.0;
  118.     break;
  119.   case CSG_INTERSECTION:
  120.     if (csg_intersection(&new_position, &new_vector, hit1, hit2,
  121.              distance1, distance2, &hit, &distance))
  122.       return 0.0;
  123.     break;
  124.   }
  125.  if (distance < min_distance)
  126.     return 0.0;
  127.   csg_copy_hit(hit, csg_hit);
  128.   if (csg_object->transf != NULL)
  129.   {
  130.     csg->position->x = new_position.x + distance * new_vector.x;
  131.     csg->position->y = new_position.y + distance * new_vector.y;
  132.     csg->position->z = new_position.z + distance * new_vector.z;
  133.     return transform_distance(csg_object->inv_transf, distance,
  134.                               &new_position, &new_vector, position);
  135.   } else
  136.     return distance;
  137. }
  138.